#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define NAME_SIZE	20
#define TEL_SIZE	14

#define TRUE		1
#define FALSE		0

struct node {
	char name[NAME_SIZE];
	char tel[TEL_SIZE];
	int age;
	struct node* next;
};

int is_text = FALSE;
int n_contacts = 0;


int usage(char* argv[])
{
	printf ("Usage: %s <file name> <file type>\n", argv[0]);
	printf ("\n");
	printf ("<file name> File name to be used as database\n");
	printf ("<file type> Type of the file (t) Text or (b) Binary\n");
	printf ("\n");
	return 0;
}
struct node* get_data()
{
	struct node* tmp;
	tmp = (struct node*) malloc(sizeof(struct node));
	int i;
	char r, c;
	i = 0;
	printf ("Enter name:");
	while ((c = getchar()) != '\n'){
		tmp->name[i] = c;
		i++;
	}
	tmp->name[i] = '\0';
	i = 0;
	printf ("Enter tel:");
	while ((c = getchar()) != '\n'){
		tmp->tel[i] = c;
		i++;
	}
	tmp->tel[i] = '\0';
	printf ("Enter age:");
	scanf ("%d", &(tmp->age));
	scanf ("%c", &r);
	n_contacts++;
	return tmp;
}

int show_list(struct node* l)
{
	struct node* aux;
	int n;
	n = 0;
	aux = l;
	if (l == NULL){
		printf ("The list is empty.\n");
		return 1;
	}
	printf ("\n");
	while (aux != NULL){
		printf("%s\t", aux->name);
		printf("%s\t", aux->tel);
		printf("%d\t", aux->age);
		n++;
		aux = aux->next;
		printf ("\n");
	}
	printf ("\n");
	printf("List has %d node(s).\n", n);
	return 0;
}
int insert_back(struct node** l)
{
	struct node* new;
	struct node* aux2;
//	new = (struct node*) malloc(sizeof(struct node));
	new = get_data();

	if (*l == NULL){
		/*List is empty*/
		*l = new;
	}
	else {
		aux2 = *l;
		while (aux2->next != NULL){
			aux2 = aux2->next;
		}
		aux2->next = new;
	}
	
	return 0;
}
int insert_front(struct node** l)
{
	struct node* aux;
//	aux = (struct node*) malloc(sizeof(struct node));
	aux = get_data();
	

	if (*l == NULL){
		*l = aux;
		(**l).next = NULL;	
	}
	else {
		aux->next = *l;
		*l = aux;
	}
	return 0;
}
int delete_node(struct node** l)
{
	struct node* aux;
	struct node* del;
	char name[NAME_SIZE];
	int i;
	char c;
	if (*l == NULL){
		printf ("The list is empty.\n");
		return 1;
	}
	aux = *l;
	printf ("Enter the name to be deleted:");
	i = 0;
	while ((c = getchar()) != '\n' ){
		name[i] = c;
		i++;
	}
	name[i] = '\0';

	while (strcmp(aux->next->name, name) != 0){ 
		if (aux->next == NULL){
			printf("Node not find.\n");
			return 1;
		}
		aux = aux->next;
	}
	del = aux->next;
	aux->next = aux->next->next;
	free(del);
	n_contacts--;
	return 0;
}
int record_data(FILE *file, struct node** l)
{
	int j, ret_fw;
	struct node* aux;
	aux = *l;
	if (*l == NULL){
		 puts("List is empty. No records to be written.");
		 return 1;
	 } else {
		 if (is_text == TRUE){
			 while (aux != NULL){
				 j = 0;
				 while (aux->name[j] != '\0'){
					 if (fputc(aux->name[j], file) == EOF){
						 puts("Error while writing the NAME struct to the file.");
						 return 1;
					 }
					 j++;
		 		}
				 fprintf(file, "\n");
				 j = 0;
				 while (aux->tel[j] != '\0'){
					 if (fputc(aux->tel[j], file) == EOF){
						 puts("Error while writing the TEL struct to the file.");
						 return 1;
					 }
					 j++;
				 }
				 fprintf(file, "\n");
				 fprintf(file, "%d\n", aux->age);
				 aux = aux->next;
			 }
		 } else {
			 if (is_text == FALSE){
				 while (aux != NULL){
					  ret_fw = fwrite(aux, sizeof(struct node), n_contacts, file);
			 	}
			printf("Binary Records written %d\n", ret_fw);
 			}
 		}
		 printf("%d records written to the file.\n", n_contacts);
        	 n_contacts = 0;
	}
	return 0;
}
int menu(void)
{
	int option;
	char r;
	printf ("Enter (1) to add node to the front.\n");
	printf ("Enter (2) to add node to the back.\n");
	printf ("Enter (3) to del node.\n");
	printf ("Enter (4) to show list.\n");
	printf ("Enter (5) to record to file.\n");
	printf ("Enter (0) to exit:");
	scanf ("%d", &option);
	scanf ("%c", &r);
	return option;
}
char  get_file_type(){
	char file_type;
	int f = FALSE;	

	do {
		printf ("Enter file type. (t) to TEXT or (b) to BINARY.\n");
		scanf ("%c",  &file_type);
		if (file_type != 't'){
			if (file_type != 'b'){
				puts ("Wrong file type");
			}
		}
		else 
			f = TRUE;
	} while (f == FALSE); 
	return file_type;
}

int readdata(FILE* file, struct contact data[], int* p_index)
{
	int i, c;
	char r;
//	puts("Inside readdata");
//	printf("*p_index = %d\n", (*p_index));
	c = fgetc(file);
	if (c != EOF){
		i = 0;
		do {
			data[*p_index].name[i] = c;
			c = fgetc(file);
			i++;
		} while (c != '\n');
		data[*p_index].name[i] = '\0';
//		printf("j = %d\n", i);

		fscanf(file, "%d", &(data[*p_index].age));
		fscanf(file, "%c", &r);

		i = 0;
		while ((c = fgetc(file)) != '\n'){
			data[*p_index].tel[i] = c;
			i++;
		} 
		data[*p_index].tel[i] = '\0';
//		printf("c = %d\n", c);
//		printf("i = %d\n", i);
		(*p_index)++;
		return 0;
	}
	else {
		return 1;
	}
}

int initfile(FILE* file, struct contact data[], int* p_index, int is_text)
{
	int ret, ret_fread;
	puts("Initializing file.");
	if (is_text == TRUE){
		printf("*p_index = %d\n", (*p_index));
		do 
		{
			ret = readdata(file, data, p_index);
			printf("*index = %d\n", (*p_index));
		} while (ret != 1);
		printf("%d contacts added.\n", (*p_index));
	} 
	else {
		while ((ret_fread = (fread(&data[*p_index], sizeof(struct contact), 1, file))) > 0){
			printf("ret_fread = %d\n", ret_fread);
			(*p_index)++;
		}
	}
	fclose(file);
	return 0;
}
int main(int argc, char* argv[]){
	struct node* list;
	list = NULL;
	int choice, first_time = FALSE;
	char file_type;
	FILE* file;
//	printf ("argv[2][0] = %c\n", argv[2][0]);
	if (argc != 3){
		usage(argv);
		return 0;
	} 
	else { 
		printf ("argv[2][0] = %c\n", argv[2][0]);
		if ((strcmp((argv[2]), "t")) != 0){
			if ((strcmp((argv[2]), "b")) != 0){
				puts("Calling get_file_type()");
				file_type = get_file_type();
			}
			else {
				strncpy(file_type, argv[2], 1);
			}
		} 
		else {
			strncpy(file_type, argv[2], 1);
		if (argv[2][0] != 'b'){
			if (argv[2][0] != 't'){
				file_type = get_file_type();
			}
		}
		printf ("%c\n", file_type);
		if (file_type == 't'){
			is_text = TRUE;
			if ((file = fopen(argv[1], "r")) == NULL){
				printf ("First time use. Opening %s file as text.\n", argv[1]);
				first_time = TRUE;
			}
		} 
		if (file_type == 'b'){
			is_text = FALSE;
			if ((file = fopen(argv[1], "br")) == NULL){
				printf ("First time use. Opening %s file as text.\n", argv[1]);
				first_time = TRUE;
			}
		}
		if (first_time == TRUE){
			initfile(file, );
		do {
			choice = menu();
			switch (choice){
				case 1:
					insert_front(&list);
					break;
				case 2:
					insert_back(&list);
					break;
				case 3:
					delete_node(&list);
					break;
				case 4:
					show_list(list);
					break;	
				case 5:
					record_data(file, &list);
					break;
				case 0:
					return 0;
					break;
				default:
					printf ("Option not found. Try again.\n");
					continue;
			}
		} while (choice != 0);
	}
	return 0;
}
#include <stdio.h>
#include "main.h"
#include <string.h>

int readdata(FILE* file, struct contact data[], int* p_index);

int initfile(FILE* file, struct contact data[], int* p_index, int is_text)
{
	int ret, ret_fread;
	puts("Initializing file.");
	if (is_text == TRUE){
		printf("*p_index = %d\n", (*p_index));
		do 
		{
			ret = readdata(file, data, p_index);
			printf("*index = %d\n", (*p_index));
		} while (ret != 1);
		printf("%d contacts added.\n", (*p_index));
	} 
	else {
		while ((ret_fread = (fread(&data[*p_index], sizeof(struct contact), 1, file))) > 0){
			printf("ret_fread = %d\n", ret_fread);
			(*p_index)++;
		}
	}
	fclose(file);
	return 0;
}

int readdata(FILE* file, struct contact data[], int* p_index)
{
	int i, c;
	char r;
//	puts("Inside readdata");
//	printf("*p_index = %d\n", (*p_index));
	c = fgetc(file);
	if (c != EOF){
		i = 0;
		do {
			data[*p_index].name[i] = c;
			c = fgetc(file);
			i++;
		} while (c != '\n');
		data[*p_index].name[i] = '\0';
//		printf("j = %d\n", i);

		fscanf(file, "%d", &(data[*p_index].age));
		fscanf(file, "%c", &r);

		i = 0;
		while ((c = fgetc(file)) != '\n'){
			data[*p_index].tel[i] = c;
			i++;
		} 
		data[*p_index].tel[i] = '\0';
//		printf("c = %d\n", c);
//		printf("i = %d\n", i);
		(*p_index)++;
		return 0;
	}
	else {
		return 1;
	}
}
